package handlers

import (
	"net/http"
	"strconv"

	commonv1 "github.com/devops-smartbot/devops-smartbot/proto/gen/go/common/v1"
	ticketv1 "github.com/devops-smartbot/devops-smartbot/proto/gen/go/ticket/v1"
	"github.com/devops-smartbot/devops-smartbot/services/api-gateway/internal/clients"
	"github.com/gin-gonic/gin"
)

type TicketHandler struct {
	ticketClient clients.TicketClient
}

func NewTicketHandler(ticketClient clients.TicketClient) *TicketHandler {
	return &TicketHandler{ticketClient: ticketClient}
}

// ListTickets handles GET /api/tickets
func (h *TicketHandler) ListTickets(c *gin.Context) {
	page, _ := strconv.ParseInt(c.DefaultQuery("page", "1"), 10, 32)
	pageSize, _ := strconv.ParseInt(c.DefaultQuery("pageSize", "20"), 10, 32)

	req := &ticketv1.ListTicketsRequest{
		Pagination: &commonv1.Pagination{
			Page:     int32(page),
			PageSize: int32(pageSize),
		},
	}

	// Add filters if provided
	if status := c.QueryArray("status"); len(status) > 0 {
		req.Status = status
	}
	if priority := c.QueryArray("priority"); len(priority) > 0 {
		req.Priority = priority
	}

	resp, err := h.ticketClient.ListTickets(c.Request.Context(), req)
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}

	c.JSON(http.StatusOK, gin.H{
		"data": resp.Tickets,
		"pagination": gin.H{
			"total":    resp.Total,
			"page":     page,
			"pageSize": pageSize,
		},
	})
}

// GetTicket handles GET /api/tickets/:id
func (h *TicketHandler) GetTicket(c *gin.Context) {
	id := c.Param("id")

	resp, err := h.ticketClient.GetTicket(c.Request.Context(), &ticketv1.GetTicketRequest{
		Id: id,
	})
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}

	if resp == nil {
		c.JSON(http.StatusNotFound, gin.H{"error": "Ticket not found"})
		return
	}

	c.JSON(http.StatusOK, resp)
}

// CreateTicket handles POST /api/tickets
func (h *TicketHandler) CreateTicket(c *gin.Context) {
	var req ticketv1.CreateTicketRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return
	}

	resp, err := h.ticketClient.CreateTicket(c.Request.Context(), &req)
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}

	c.JSON(http.StatusCreated, resp)
}

// GetTicketStatistics handles GET /api/tickets/statistics
func (h *TicketHandler) GetTicketStatistics(c *gin.Context) {
	resp, err := h.ticketClient.GetTicketStatistics(c.Request.Context(), &ticketv1.GetTicketStatisticsRequest{})
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}

	c.JSON(http.StatusOK, gin.H{
		"data": gin.H{
			"open":        resp.Open,
			"in_progress": resp.InProgress,
			"resolved":    resp.Resolved,
			"closed":      resp.Closed,
			"total":       resp.Total,
		},
	})
}

// UpdateTicket handles PATCH /api/tickets/:id
func (h *TicketHandler) UpdateTicket(c *gin.Context) {
	id := c.Param("id")

	var req ticketv1.UpdateTicketRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return
	}

	req.Id = id

	resp, err := h.ticketClient.UpdateTicket(c.Request.Context(), &req)
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}

	c.JSON(http.StatusOK, resp)
}

// AddComment handles POST /api/tickets/:id/comment
func (h *TicketHandler) AddComment(c *gin.Context) {
	id := c.Param("id")

	var req struct {
		Content    string `json:"content" binding:"required"`
		IsInternal bool   `json:"isInternal"`
	}

	if err := c.ShouldBindJSON(&req); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return
	}

	// Call ticket service to add comment
	resp, err := h.ticketClient.AddComment(c.Request.Context(), &ticketv1.AddCommentRequest{
		TicketId:   id,
		Content:    req.Content,
		UserName:   "admin", // TODO: Get from JWT token
		IsInternal: req.IsInternal,
	})
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}

	c.JSON(http.StatusOK, resp)
}
